package com.lobov.entities.yale;

import java.io.Serializable;
import java.util.Arrays;

import com.lobov.entities.EntityIface;
import com.lobov.utils.Compressor;

/**
 * 
 * Строка в матрице йельского формата
 * 
 */
public class SparseVector implements EntityIface, Serializable {

	public SparseVector(int xLength, int yPosition, double[] values, int[] xs,
			boolean compressed) {
		super();
		this.xLength = xLength;
		this.yPosition = yPosition;
		this.values = values;
		this.xs = xs;
		this.compressed = compressed;
	}

	private int xLength;
	private int yPosition;
	private double[] values;
	private int xs[];
	public boolean compressed;

	@Override
	public boolean isCompressed() {
		return compressed;
	}

	@Override
	public EntityIface compress() throws Exception {
		SparseVector vector = Compressor.compressSparseVector(this);
		return vector;
	}

	@Override
	public EntityIface deCompress() throws Exception {
		// TODO Auto-generated method stub
		compressed = false;
		return null;
	}

	@Override
	public double getElementByX(int x) throws Exception {
		if (x > xLength) {
			throw new Exception("Выход за пределы вектора " + yPosition
					+ "й строки");
		}
		if (compressed) { // если вектор сжат
			int pos = 0;
			if (xs == null || xs.length == 0) {
				return 0d;
			} else {
				return findValue(x);
			}
		} else { // если вектор не сжат
			return values[x];
		}
	}
	
	
	private double findValue(int position) {
		int x = Arrays.binarySearch(xs, position);
		if (x > 0) {
			return values[x];
		} else {
			return 0d;
		}
	}
	

	/**
	 * не используется в данном типе!!! всегда возвращает 0
	 */
	@Override
	public double getElementByXY(int x, int y) throws Exception {
		// TODO Auto-generated method stub
		return 0;
	}

	public int getxLength() {
		int length = 0;
		if(xLength == 0){
			return values.length;
		} else
		return xLength;
	}

	public void setxLength(int xLength) {
		this.xLength = xLength;
	}

	public int getyPosition() {
		return yPosition;
	}

	public void setyPosition(int yPosition) {
		this.yPosition = yPosition;
	}

	public double[] getValues() {
		return values;
	}

	public void setValues(double[] values) {
		this.values = values;
	}

	public void setCompressed(boolean compressed) {
		this.compressed = compressed;
	}

	@Override
	public void setElementByX(int x, double value) throws Exception {
		if (isCompressed()) {
			throw new Exception(
					"Внимание!!! Ошибка!!! Нельзя вставлять данные в сжатый вектор!");
		}
		values[x] = value;
	}

	public int[] getXs() {
		return xs;
	}

	/**
	 * unused!!!
	 */
	@Override
	public void setElementByXY(int x, int y, double value) throws Exception {
		// TODO Auto-generated method stub
	}
	
}
